<template>
  <div ref="container">
    <el-container class="designer-container">
      <el-aside v-if="!isPrint" width="200px">
        <left-aside ref="left-aside" hidden-tool></left-aside>
      </el-aside>

      <el-container class="designer-center-container" direction="vertical">
        <div v-if="!isPrint" class="search-box">
          <yrt-editor ref="editor" v-bind="editorOptions" edit-type="inner" :data-options="dataOptions" action="search" :visible.sync="editorOptions.config.visible" :auth-nodes="authNodes" :style="{'max-width':editorOptions.config.width}">
          </yrt-editor>
          <div v-if="!editorOptions.fields.length" class="no-search">未设置查询条件</div>
          <div class="btn-box">
            <el-button type="primary" @click="searchData(1)">查询数据</el-button>
            <el-button @click="reset">重置</el-button>
          </div>
        </div>
        <div class="body-box">
          <div class="tool-box no-print">
            <el-button-group>
              <el-button class="btn" @click="onlinePrint"><img :src="iconUrl+'print.svg'" title="在线打印" class="img" />Web打印</el-button>
              <!-- <el-button class="btn"><img :src="iconUrl+'pdf-print.svg'" title="PDF在线预览打印" class="img" />PDF在线打印</el-button> -->
              <el-button class="btn" @click="exportPDF"><img :src="iconUrl+'pdf.svg'" title="导出PDF" class="img" />导出PDF</el-button>
              <!-- <el-button class="btn"><img :src="iconUrl+'pdf-direct-print.svg'" title="PDF在线打印" class="img" /></el-button>
              <el-button class="btn"><img :src="iconUrl+'word.svg'" title="导出WORD" class="img" /></el-button> -->
              <el-button class="btn" @click="exportExcel('all')"><img :src="iconUrl+'excel.svg'" title="导出EXCEL" class="img" />导出EXCEL</el-button>
              <el-button class="btn" @click="exportExcel('paging')"><img :src="iconUrl+'excel-paging.svg'" title="分页导出EXCEL" class="img" />分页导出</el-button>
              <el-button class="btn" @click="exportExcel('sheet')"><img :src="iconUrl+'excel-with-paging-sheet.svg'" title="分页分Sheet导出EXCEL" class="img" />分sheet导出</el-button>
            </el-button-group>
          </div>
          <div id="bi-content" :class="'content-box'+(isPrint?' is-print':'')" v-html="reportData.content">
          </div>
          <div v-if="dataOptions.totalPage>1" class="pagination-container no-print">
            <el-pagination :current-page.sync="dataOptions.pageIndex" :page-size="dataOptions.pageSize" :total="dataOptions.total" background layout="total, prev, pager, next, jumper" @current-change="handleCurrentChange">
            </el-pagination>
          </div>
        </div>
      </el-container>
    </el-container>
    <!-- <iframe id="_print_frame" name="_print_frame" src="" frameborder="0"></iframe> -->
  </div>
</template>

<script>
import { pointToMM } from "./util/Utils.js";
import yrtEditor from "@/components/common/yrtEditor";
import LeftAside from "./components/leftAside";
import eventBus from "@/utils/eventBus";
import moment from "moment";
import $ from "jquery";
import UReportDesigner from "./util/designer.js";
import Chart from "chart.js/auto";
window.$ = $;
window.jQuery = $;

export default {
  name: "sys-dev-tools-bi-viewer",
  components: {
    yrtEditor,
    LeftAside,
  },
  data() {
    return {
      designer: {},
      iconUrl: "https://auod-beijing.oss-cn-beijing.aliyuncs.com/ureport/icon/",
      reportData: {
        content: "<span class='color-666'>暂无数据</span>",
      },
      dataOptions: {},
      editorOptions: {
        fields: [],
        config: {
          title: "查询条件",
          visible: true,
          width: "1200px",
        },
      },
      authNodes: {},
      moduleNode: {},
      isPrint: false, // 是否打印模式
    };
  },
  mounted() {
    this.designer = new UReportDesigner(null, this);
    this.bindEvent();
    this.isPrint = this.$route.path.indexOf("/ureport/print") >= 0;
    if (this.isPrint) {
      this.moduleNode = {
        reportFileName: this.$route.query._u,
      };
      this.searchData(1);
    }
  },
  methods: {
    // 事件处理
    bindEvent() {
      // 左侧导航改变事件
      eventBus.$on("bi-left-node-change", ({ node, data }) => {
        if (this.$route.path.indexOf("/ureport/viewer") >= 0) {
          this.doViewer(node, data);
        }
      });
    },
    // 浏览报表
    doViewer(node, data) {
      this.moduleNode = data;
      this.$refs.editor.formData = {}; // 清空数据
      if (data.vueData) {
        const config = JSON.parse(data.vueData);
        this.dataOptions = config.dataOptions;
        this.editorOptions = config.editorOptions;
        this.editorOptions.config.title = data.label;
        this.editorOptions.config.action = "search";
        window.setTimeout(() => {
          this.$refs.editor.reLoadDropDown(false); // 加载下拉框
        }, 500);
      } else {
        this.dataOptions = {};
        this.editorOptions = {
          fields: [],
          config: {
            title: "查询条件[无查询条件]",
            action: "search",
          },
        };
      }

      this.searchData(1);
    },
    loadStyle(style) {
      let link = document.getElementById("tableStyle");
      if (!link) {
        link = document.createElement("style");
        link.type = "text/css";
        link.rel = "stylesheet";
        link.id = "tableStyle";
      }
      link.innerHTML = style; // css链接
      var head = document.getElementsByTagName("head")[0];
      head.appendChild(link);
    },
    getWhere() {
      // 获得查询条件
      const where = {};
      // url条件
      const id = this.$route.query.id;
      if (id) {
        where.id = id;
      }

      if (!this.$refs.editor) {
        return where;
      }
      const formData = this.$refs.editor.formData;
      const getWhere = function (array) {
        array.forEach((item) => {
          if (item.type === "grid") {
            item.columns.forEach((colItem) => {
              getWhere(colItem.fields);
            });
          } else if (item.type === "inline-group") {
            getWhere(item.fields);
          } else if (item.type === "detail-grid") {
            getWhere(item.fields);
          } else {
            const prop = item.options.keyProp || item.options.prop;
            const dataType = item.options.dataType;
            if (!prop) {
              return;
            }
            const value = formData[prop];
            if (!value) return;

            if (["date", "datetime"].indexOf(dataType) >= 0) {
              const format = item.options.formatter || "YYYY-MM-DD";
              where[prop] = moment(value).format(format);
              if (prop.indexOf("end") === 0) {
                where[prop] += " 23:59:59";
              }
            } else if (Array.isArray(value)) {
              where[prop] = value.join(",");
            } else {
              where[prop] = value;
            }
          }
        });
      };
      getWhere(this.editorOptions.fields);

      return where;
    },
    // 查询数据
    searchData(pageIndex = 1) {
      if (!this.moduleNode.reportFileName) {
        this.$message.error("请选择左侧模块节点");
        return;
      }
      this.dataOptions.pageIndex = pageIndex;
      this.dataOptions.total = 0;
      this.reportData.content = ""; // 清空内容

      const where = this.getWhere();
      const url = "/html/viewer";
      const fileName = `file:${this.moduleNode.reportFileName}`;
      let ajaxData = {
        _u: fileName,
        _i: pageIndex,
      };
      ajaxData = Object.assign(ajaxData, where);
      this.designer.ajax(url, ajaxData, (res) => {
        if (res.code === 200) {
          this.reportData = res.data;
          this.loadStyle(this.reportData.style);
          const totalRows = res.data.totalRows - 1;
          this.dataOptions.total = totalRows; // 减去表头
          const pageSize = Math.ceil(totalRows / res.data.totalPage);
          this.dataOptions.pageSize = pageSize;
          this.dataOptions.totalPage = res.data.totalPage;
          this.dataOptions.pageIndex = pageIndex;
          console.log(
            "totalRows=",
            totalRows,
            "pageSize=",
            pageSize,
            "totalPage=",
            res.data.totalPage
          );
          this.$nextTick(() => {
            this.buildChartDatas(this.reportData.chartDatas);
          });
        } else {
          this.$message.error("获取数据错误：" + res.msg);
        }
      });
    },
    // 当前页码大小改变
    handleCurrentChange(pageIndex) {
      this.dataOptions.pageIndex = pageIndex;
      this.searchData(pageIndex);
    },
    reset() {
      const formData = this.$refs.editor.formData;
      Object.keys(formData).forEach((key) => {
        formData[key] = null;
      });
    },
    // 在线打印
    async onlinePrint() {
      window.print();
      // const where = this.getWhere();
      // const url = "/html/loadPrintPages";
      // const fileName = `file:${this.moduleNode.reportFileName}`;
      // let ajaxData = {
      //   _u: fileName
      // };

      // ajaxData = Object.assign(ajaxData, where);
      // const res = await this.designer.ajax(url, ajaxData);
      // if (res.code === 200) {
      //   const resPage = await this.loadPagePaper();
      //   const html = res.data.html;
      //   const iFrame = window.frames["_print_frame"];
      //   let styles = `<style type="text/css">`;
      //   styles += this.buildPrintStyle(resPage.data);
      //   styles += $("#tableStyle").html();
      //   styles += `</style>`;
      //   $(iFrame.document.body).html(styles + html);
      //   window.setTimeout(() => {
      //     iFrame.window.focus();
      //     iFrame.window.print();
      //   }, 2000);
      // } else {
      //   this.$message.error("获取数据错误：" + res.msg);
      // }
    },
    // 导出PDF
    exportPDF() {
      const where = this.getWhere();
      const params = Object.keys(where)
        .map((key) => {
          return key + "=" + where[key];
        })
        .join("&");
      const userInfo = this.common.getUserInfo();
      const url = `${this.designer.server}/pdf?userFolder=${userInfo.keys}&_u=file:${this.moduleNode.reportFileName}&${params}`;
      window.open(url);
    },
    // 导出excel
    exportExcel(type) {
      const where = this.getWhere();
      const params = Object.keys(where)
        .map((key) => {
          return key + "=" + where[key];
        })
        .join("&");
      const userInfo = this.common.getUserInfo();
      const url = `${this.designer.server}/excel/${type}?userFolder=${userInfo.keys}&_u=file:${this.moduleNode.reportFileName}&${params}`;
      window.open(url);
    },
    // 构建打印样式
    buildPrintStyle(paper) {
      const marginLeft = pointToMM(paper.leftMargin);
      const marginTop = pointToMM(paper.topMargin);
      const marginRight = pointToMM(paper.rightMargin);
      const marginBottom = pointToMM(paper.bottomMargin);
      const paperType = paper.paperType;
      let page = paperType;
      if (paperType === "CUSTOM") {
        page = pointToMM(paper.width) + "mm " + pointToMM(paper.height) + "mm";
      }
      const style = `
        @media print {
            .page-break{
                display: block;
                page-break-before: always;
            }
        }
        @page {
          size: ${page} ${paper.orientation};
          margin-left: ${marginLeft}mm;
          margin-top: ${marginTop}mm;
          margin-right:${marginRight}mm;
          margin-bottom:${marginBottom}mm;
        }
    `;
      return style;
    },
    // 获取打印信息
    async loadPagePaper() {
      const where = this.getWhere();
      const url = "/html/loadPagePaper";
      const fileName = `file:${this.moduleNode.reportFileName}`;
      let ajaxData = {
        _u: fileName,
      };

      ajaxData = Object.assign(ajaxData, where);
      const page = await this.designer.ajax(url, ajaxData);

      return page;
    },
    buildChartDatas(chartDatas) {
      if (!chartDatas) {
        return;
      }
      chartDatas = JSON.parse(chartDatas);
      for (const d of chartDatas) {
        let json = d.json;
        json = JSON.parse(json, function (k, v) {
          if (v.indexOf && v.indexOf("function") >= 0) {
            // eslint-disable-next-line
            return eval("(function(){return " + v + " })()");
          }
          return v;
        });
        this.buildChart(d.id, json);
      }
    },
    buildChart(canvasId, chartJson) {
      const ctx = document.getElementById(canvasId);
      if (!ctx) {
        return;
      }
      let options = chartJson.options;
      if (!options) {
        options = {};
        chartJson.options = options;
      }
      if (options.title) {
        options.plugins.title = options.title;
      }
      if (options.legend) {
        options.plugins.legend = options.legend;
      }

      let animation = options.animation;
      if (!animation) {
        animation = {};
        options.animation = animation;
      }
      animation.onComplete = (event) => {
        const chart = event.chart;
        const base64Image = chart.toBase64Image();
        const where = this.getWhere();
        const url = "/chart/storeData";
        const canvas = $("#" + canvasId);
        const width = parseInt(canvas.css("width"));
        const height = parseInt(canvas.css("height"));
        const fileName = `file:${this.moduleNode.reportFileName}`;
        let data = {
          _u: fileName,
          _base64Data: base64Image,
          _chartId: canvasId,
          _width: width,
          _height: height,
        };
        data = Object.assign(data, where);
        this.designer.ajax(url, data, (res) => {});
      };
      this.chart = new Chart(ctx, chartJson);
    },
  },
};
</script>

<style lang="scss" scoped>
@import "./styles/index.scss";
.designer-center-container {
  background: #f3f5f7;
  border-left: 0px solid #e0e0e0;
  border-right: 0px solid #e0e0e0;
  ::v-deep .frame .inner {
    margin-bottom: 5px;
  }
  ::v-deep .frame .title {
    margin-left: 0px;
    padding-left: 0px;
  }
  ::v-deep .editor-container {
    margin-bottom: 0;
    padding-bottom: 0px;
  }
  ::v-deep .el-form-item {
    margin-bottom: 10px;
  }
}
.search-box {
  background: #ffffff;
  margin-bottom: 10px;
  border-radius: 5px;
  margin-left: 5px;
  padding-left: 10px;
  padding-right: 10px;
  .no-search {
    color: #666;
    margin-bottom: 20px;
  }
  .btn-box {
    padding-bottom: 10px;
  }
}
.body-box {
  margin-left: 5px;
  border-radius: 5px;
  background: #ffffff;
  .tool-box {
    padding: 5px;
    .btn {
      padding: 5px 10px;
      img {
        vertical-align: middle;
        margin-right: 5px;
      }
    }
    .img {
      width: 22px;
      height: 22px;
    }
  }
  .content-box {
    text-align: left;
    min-height: 500px;
    overflow: auto;
    padding: 5px;
    max-height: calc(100vh - 410px);
    &.is-print {
      max-height: none;
    }
  }
  .pagination-container {
    margin-bottom: 10px;
  }
}

@media print {
  .no-print {
    display: none;
  }
  .body-box {
    padding: 0px;
    margin: 0px;
    .content-box {
      padding: 0px;
      margin: 0px;
      max-height: none;
    }
  }
}
</style>

<style lang="scss">
.bi-content {
  td {
    word-break: break-all;
    word-wrap: break-word;
    white-space: pre-wrap;
  }
}
</style>
